/*
 * Copyright (C) 2008 Universidade Federal de Campina Grande
 *  
 * This file is part of OurGrid. 
 *
 * OurGrid is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free 
 * Software Foundation, either version 3 of the License, or (at your option) 
 * any later version. 
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details. 
 * 
 * You should have received a copy of the GNU Lesser General Public License 
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package org.ourgrid.acceptance.worker;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;
import org.ourgrid.acceptance.util.WorkerAcceptanceUtil;
import org.ourgrid.acceptance.util.worker.Req_004_Util;
import org.ourgrid.acceptance.util.worker.Req_006_Util;
import org.ourgrid.acceptance.util.worker.Req_079_Util;
import org.ourgrid.acceptance.util.worker.Req_087_Util;
import org.ourgrid.acceptance.util.worker.Req_088_Util;
import org.ourgrid.acceptance.util.worker.Req_090_Util;
import org.ourgrid.acceptance.util.worker.Req_092_Util;
import org.ourgrid.acceptance.util.worker.Req_121_Util;
import org.ourgrid.common.interfaces.Worker;
import org.ourgrid.common.interfaces.management.RemoteWorkerManagementClient;
import org.ourgrid.common.interfaces.management.WorkerManagementClient;
import org.ourgrid.common.interfaces.to.WorkerStatus;
import org.ourgrid.reqtrace.ReqTest;
import org.ourgrid.worker.WorkerComponent;

import br.edu.ufcg.lsd.commune.identification.ContainerID;
import br.edu.ufcg.lsd.commune.identification.DeploymentID;

@ReqTest(reqs="REQ121")
public class Req_121_Test extends WorkerAcceptanceTestCase {
	
	private DeploymentID peerID;
	private Req_004_Util req_004_Util = new Req_004_Util(getComponentContext());
	private Req_090_Util req_090_Util = new Req_090_Util(getComponentContext());
	private Req_092_Util req_092_Util = new Req_092_Util(getComponentContext());
	private Req_079_Util req_079_Util = new Req_079_Util(getComponentContext());
	private Req_006_Util req_006_Util = new Req_006_Util(getComponentContext());
	private Req_121_Util req_121_Util = new Req_121_Util(getComponentContext());
	private Req_087_Util req_087_Util = new Req_087_Util(getComponentContext());
	private Req_088_Util req_088_Util = new Req_088_Util(getComponentContext());
	
	@Before
	public void setUp() throws Exception {
		super.setUp();
		String peerPubKey = workerAcceptanceUtil.simulateAuthentication();
		
		peerID = new DeploymentID(new ContainerID("username", "server", "module", peerPubKey), "peer");
		
	}

	/**
	 * This test contains the following steps:
	 * 
	 *    1. Start a Worker with the master peer public key property: "publicKey1" and the idleness detector DISABLED;
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [publickey222]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    4. A remote peer with the public key "publicKeyABC" sends a remote workFoMyGrid message to the Worker;
	 *           * Verify if the following warn message was logged: "An unknown remote peer tried to command this Worker to work for a remote consumer. This message was ignored. Unknown remote peer public key: [publicKeyABC]."
	 *    5. Verify if the WORKER object is NOT bound
	 *    6. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [publickeyABC]."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    7. A remote peer with the public key "publicKey222" sends a remote workFoMyGrid message to the Worker;
	 *           * Verify if the following warn message was logged: "An unknown remote peer tried to command this Worker to work for a remote consumer. This message was ignored. Unknown remote peer public key: [publicKey222]."
	 *    8. Verify if the WORKER object is NOT bound
	 *    9. A remote peer with the public key "publicKey1" sends a remote workForMyGrid message to the Worker;
	 *           * Verify if the following warn message was logged: "An unknown remote peer tried to command this Worker to work for a remote consumer. This message was ignored. Unknown remote peer public key: [publicKey1]."
	 *   10. Verify if the WORKER object is NOT bound
	 *  
	 */
	@ReqTest(test=" AT-121.1", reqs="REQ121")
	@Test public void test_at_121_1_UnknownPeerCommandsWorkerToWorkForPeer() throws Exception {
		//Start Worker with idleness detector DISABLED
		WorkerComponent component = req_004_Util.startWorker();

		//Master peer sends a setPeer message
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "publickey222");
		
		//A remote peer with the public key "publicKeyABC" sends a remote workFoMyGrid message
		// expect a warn to be logged
		req_121_Util.workForMyGridByUnknownRemotePeer(component, "publicKeyABC");
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnAllocatedForPeerWorker(component, wmc, peerID.getPublicKey(), "publicKeyABC");
		
		//A remote peer with the public key "publicKey222" sends a remote workFoMyGrid message
		// expect a warn to be logged
		req_121_Util.workForMyGridByUnknownRemotePeer(component, "publicKey222");
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//A remote peer with the public key "publicKey1" sends a remote workFoMyGrid message
		// expect a warn to be logged
		req_121_Util.workForMyGridByUnknownRemotePeer(component, "publicKey1");
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
	} 
	
	/**
	 * This test contains the following steps:
	 * 
	 *    1. Start a Worker with the idleness detector DISABLED;
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    4. Verify if the WORKER object is NOT bound
	 *    5. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "mgPubKey";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [mgPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    6. Verify if the WORKER object is bound
	 *    7. Pause the Worker;
	 *           * Verify if the following info message was logged: "Worker has been PAUSED."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_MYGRID to OWNER."
	 *           * Expect the Worker to send the peer a status changed message, with the OWNER status
	 *    8. Verify if the WORKER object is NOT bound
	 *    9. Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
	 *   10. Resume the Worker;
	 *           * Verify if the following info message was logged: "Worker has been RESUMED."
	 *           * Verify if the following debug message was logged: "Status changed from OWNER to IDLE."
	 *           * Verify if the ControlClient received the operation succeed message
	 *   11. Verify if the WORKER object is NOT bound
	 *   12. Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
	 * 
	 */
	@ReqTest(test=" AT-121.2", reqs="REQ121")
	@Test public void test_at_121_2_IdleWorkerIsCommandedToWorkForMyGrid() throws Exception {
		//Start Worker with idleness detector DISABLED
		WorkerComponent component = req_004_Util.startWorker();

		//Master peer sends a setPeer message
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "peerPubKey");
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "mgPubKey"
		RemoteWorkerManagementClient rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey", "mgPubKey");
		req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//Verify if the WORKER is bound
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		
		//Pause Worker
		req_087_Util.pauseAllocatedForMyGridWorker(component, wmc);
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Resume Worker
		req_088_Util.resumeOwnerWorker(wmc, component);
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
	}
	
	/**
	 * This test contains the following steps:
	 * 
	 *    1. Start a Worker with the idleness detector DISABLED;
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 
	 *    4. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "mgPubKey";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [mgPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 
	 *    5. A client with the public key "mgPublicKey222" sends a startWork message;
	 *           * Verify if the following warn message was logged: An unknown client tried to start the work of this Worker. This message was ignored. Unknown client public key: [mgPublicKey222].
	 
	 *    6. The remote peer with the public key "peerPubKey" commands the Worker to work for the client with the public key "publicKeyABC";
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a local consumer. Local consumer public key: [publicKeyABC]."
	 *           * Verify if the following debug message was logged: "Cleaning Worker."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	
	 *    7. A client with the public key "mgPubKey" sends a startWork message;
	 *           * Verify if the following warn message was logged: An unknown client tried to start the work of this Worker. This message was ignored. Unknown client public key: [mgPubKey].
	 * 
	 */
	@ReqTest(test=" AT-121.3", reqs="REQ121")
	@Test public void test_at_121_3_UnknownRemoteClientTriesToStartWork() throws Exception {
		//Start Worker with idleness detector DISABLED
		WorkerComponent component = req_004_Util.startWorker();

		//Master peer sends a setPeer message
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "peerPubKey");
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "mgPubKey"
		RemoteWorkerManagementClient rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey", "mgPubKey");
		Worker worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//A client [mgPublicKey222] sends a startWork message - expected a warn to be logged
		DeploymentID unknownMyGridID = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "mgPubKey222"), "myGrid");
		
		req_079_Util.startWorkByUnknownClient(component, worker, "mgPubKey222", unknownMyGridID);
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "publicKeyABC"
		rwmc = req_121_Util.workForMyGridOnAllocatedForMyGridWorker(component, "peerPubKey", "publicKeyABC");
		worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//A client [mgPubKey] sends a startWork message - expected a warn to be logged
		unknownMyGridID = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "mgPubKey"), "myGrid");
		
		req_079_Util.startWorkByUnknownClient(component, worker, "mgPubKey", unknownMyGridID);
	}
	
	/**
	 * This test contains the following steps:
	 * 
	 *    1.  Start a Worker with the idleness detector DISABLED and the playpen root property set to a read-only directory;
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    4. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "mgPubKey";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [mgPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    5. A client with the public key "mgPublicKey1" sends a startWork message;
	 *           * Verify if the following error message was logged: The client [clientID] tried to start the work of this Worker, but the playpen directory [playpenDir] cannot be created.
	 *           * Expect the Worker to send the client an error ocurred message with the IO_ERROR type
	 * 
	 */
	@ReqTest(test=" AT-121.4", reqs="REQ121")
	@Test public void test_at_121_4_RemoteClientStartWorkWithError() throws Exception {
		//Creating read-only playpen root directory
		WorkerAcceptanceUtil.createDirectory(WorkerAcceptanceUtil.DEF_PLAYPEN_ROOT_PATH, true);
		
		//Start worker without idleness detector
		WorkerComponent component = req_004_Util.startWorker(false, true, false);
		
		//Master peer sends setPeer to the worker
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "peerPubKey");
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "mgPubKey"
		RemoteWorkerManagementClient rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey", "mgPubKey");
		Worker worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//A client [mgPubKey] sends a startWork message - expected a warn to be logged
		DeploymentID myGridID = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "mgPubKey"), "myGrid");
		
		req_079_Util.startWorkWithPlaypenError(component, worker, myGridID, WorkerAcceptanceUtil.DEF_PLAYPEN_ROOT_PATH);
	}
	
	/**
	 * This test contains the following steps:
	 * 
	 *    1. Start a Worker with the idleness detector DISABLED;
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    4. Resume the Worker;
	 *           * Verify if the ControlClient received the operation succeed message
	 *    5. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "mgPubKey";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [mgPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    6. Resume the Worker;
	 *           * Verify if the ControlClient received the operation succeed message
	 *    7. A client with the public key "mgPubKey" sends a startWork message;
	 *           * Verify if the following info message was logged: Worker is ready to start working for client [ClientID].
	 *           * Expect the Worker to send the client a Worker is Ready message
	 *    8. Resume the Worker;
	 *           * Verify if the ControlClient received the operation succeed message
	 *    9. Verify if the WORKER object is bound
	 *   10. Verify if the REMOTE_WORKER_MANAGEMENT object is bound
	 *   11. Pause the Worker;
	 *           * Verify if the following info message was logged: "Worker has been PAUSED."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_MYGRID to OWNER."
	 *           * Expect the Worker to send the peer a status changed message, with the OWNER status
	 *   12. Verify if the WORKER object is NOT bound
	 *   13. Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
	 *   14. Resume the Worker;
	 *           * Verify if the following info message was logged: "Worker has been RESUMED."
	 *           * Verify if the following debug message was logged: "Status changed from OWNER to IDLE."
	 *           * Verify if the ControlClient received the operation succeed message
	 *   15. Verify if the WORKER object is NOT bound
	 *   16. Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
	 * 
	 */
	@ReqTest(test=" AT-121.5", reqs="REQ121")
	@Test public void test_at_121_5_WorkerWorkingForClientIsPaused() throws Exception {
		//Start Worker with idleness detector DISABLED
		WorkerComponent component = req_004_Util.startWorker();

		//Master peer sends a setPeer message
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(
				component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "peerPubKey");
		
		//Resume Worker
		req_088_Util.resumeNotOwnerWorker(component);
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "mgPubKey"
		RemoteWorkerManagementClient rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey", "mgPubKey");
		Worker worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//Resume Worker
		req_088_Util.resumeNotOwnerWorker(component);
		
		//A client with the public key "mgPubKey" sends a startWork message
		DeploymentID myGridID = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "mgPubKey"), "myGrid");
		
		req_079_Util.startWorkSuccessfully(component, worker, myGridID);
		
		//Resume Worker
		req_088_Util.resumeNotOwnerWorker(component);
		
		//Verify if the WORKER is bound
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT object is bound
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		
		//Pause the Worker
		req_087_Util.pauseAllocatedForMyGridWorker(component, wmc);
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Resume Worker
		req_088_Util.resumeOwnerWorker(wmc, component);
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
	}
	
	/**
	 * This test contains the following steps:
	 * 
	 *    1. Start a Worker with the idleness detector DISABLED;
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    4. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "mgPubKey";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [mgPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    5. A client with the public key "mgPubKey" sends a startWork message;
	 *           * Verify if the following info message was logged: Worker is ready to start working for client [ClientID].
	 *           * Expect the Worker to send the client a Worker is Ready message
	 *    6. Verify if the WORKER object is bound
	 *    7. Verify if the REMOTE_WORKER_MANAGEMENT object is bound and get its DeploymentID (objIDA)
	 *    8. The master peer sends a workForPeer message to the Worker, with a different public key;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey222]."
	 *           * Verify if the following debug message was logged: "Cleaning Worker."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_MYGRID to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    9. Verify if the WORKER object is NOT bound
	 *   10. Verify if the REMOTE_WORKER_MANAGEMENT object is bound and get its DeploymentID (objIDB)
	 *           * Expect objIDB to be different from objIDA
	 *   11. The remote peer with the public key "peerPubKey222" commands the Worker to work for the remote client with the public key "mgPubKey222";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [mgPubKey222]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *   12. Verify if the WORKER object is bound
	 *   13. Verify if the REMOTE_WORKER_MANAGEMENT object is bound
	 *   14. The master peer sends a workForPeer message to the Worker, with a different public key;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey333]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_MYGRID to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *   15. Verify if the WORKER object is NOT bound
	 *   16. Verify if the REMOTE_WORKER_MANAGEMENT object is bound
	 * 
	 */
	@ReqTest(test=" AT-121.6", reqs="REQ121")
	@Test public void test_at_121_6_AllocatedWorkerForRemoteConsumerIsCommandedToWorkForRemotePeer() throws Exception {
		//Start Worker with idleness detector DISABLED
		WorkerComponent component = req_004_Util.startWorker();

		//Master peer sends a setPeer message
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(
				component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "peerPubKey");
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "mgPubKey"
		RemoteWorkerManagementClient rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey", "mgPubKey");
		Worker worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//A client with the public key "mgPubKey" sends a startWork message
		DeploymentID myGridID = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "mgPubKey"), "myGrid");
		
		req_079_Util.startWorkSuccessfully(component, worker, myGridID);
		
		//Verify if the WORKER is bound
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT is bound and get its DeploymentID (objIDA)
		assertTrue(workerAcceptanceUtil.isRemoteWorkerManagementBound());
		DeploymentID workerAObjID = workerAcceptanceUtil.getRemoteWorkerManagementDeployment().getDeploymentID();
		
		//The master peer sends a workForPeer message with a different public key "peerPubKey222"
		req_006_Util.workForPeerOnAllocatedForMyGridWorker(component, wmc, peerID.getPublicKey(), "peerPubKey222");
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT is bound and get its DeploymentID (objIDB)
		assertTrue(workerAcceptanceUtil.isRemoteWorkerManagementBound());
		DeploymentID workerBObjID = workerAcceptanceUtil.getRemoteWorkerManagementDeployment().getDeploymentID();
		
		//Expect objIDB to be different from objIDA
		assertFalse(workerBObjID.equals(workerAObjID));
		
		//The remote peer with the public key "peerPubKey222" commands the Worker 
		// to work for the remote client with the public key "mgPubKey222"
		rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey222", "mgPubKey222");
		worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//Verify if the WORKER is bound
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT is bound
		assertTrue(workerAcceptanceUtil.isRemoteWorkerManagementBound());
		
		//The master peer sends a workForPeer message with a different public key "peerPubKey333"
		req_006_Util.workForPeerOnAllocatedForMyGridWorker(component, wmc, peerID.getPublicKey(), "peerPubKey333");
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//Verify if the REMOTE_WORKER_MANAGEMENT is bound
		assertTrue(workerAcceptanceUtil.isRemoteWorkerManagementBound());
	}
	
	/**
	 * This test contains the following steps:
	 * 
	 *    1. Start a Worker with the idleness detector DISABLED;
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    4. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "remoteMgPubKey";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [remoteMgPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    5. A client with the public key "remoteMgPubKey" sends a startWork message;
	 *           * Verify if the following info message was logged: Worker is ready to start working for client [ClientID].
	 *           * Expect the Worker to send the client a Worker is Ready message
	 *    6. Verify if the REMOTE_WORKER_MANAGEMENT object is bound
	 *    7. Verify if the WORKER object is bound and get its DeploymentID (objIDA)
	 *    8. The master peer sends a workForMyGrid message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a local consumer. Local consumer public key: [localMgPubKey]."
	 *           * Verify if the following debug message was logged: "Cleaning Worker."
	 *           * Expect the Worker to send the peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    9. Verify if the REMOTE_WORKER_MANAGEMENT object is NOT bound
	 *   10. Verify if the WORKER object is bound and get its DeploymentID (objIDB)
	 *           * Expect objIDB to be different from objIDA
	 * 
	 */
	@ReqTest(test=" AT-121.7", reqs="REQ121")
	@Test public void test_at_121_7_AllocatedWorkerForRemoteConsumerIsCommandedToWorkForLocalConsumer() throws Exception {
		//Start Worker with idleness detector DISABLED
		WorkerComponent component = req_004_Util.startWorker();
		
		//Master peer sends a setPeer message
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(
				component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "peerPubKey");
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "mgPubKey"
		RemoteWorkerManagementClient rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey", "remoteMgPubKey");
		Worker worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//A client with the public key "remoteMgPubKey" sends a startWork message
		DeploymentID myGridID = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "remoteMgPubKey"), "myGrid");
		
		req_079_Util.startWorkSuccessfully(component, worker, myGridID);
		
		//Verify if the REMOTE_WORKER_MANAGEMENT is bound
		assertTrue(workerAcceptanceUtil.isRemoteWorkerManagementBound());
		
		//Verify if the WORKER is bound and get its DeploymentID (objIDA)
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		DeploymentID workerAObjID = workerAcceptanceUtil.getWorkerDeployment().getDeploymentID();
		
		//The master peer sends a workForMyGrid message the Worker
		// to work for the local client with public key "localMgPubKey"
		req_092_Util.workForMyGridOnAllocatedForMyGridWorker(component, wmc, "localMgPubKey");
		req_092_Util.beginAllocationCompleted(component, wmc);
		
		//Verify if the REMOTE_WORKER_MANAGEMENT is NOT bound
		assertFalse(workerAcceptanceUtil.isRemoteWorkerManagementBound());
		
		//Verify if the WORKER is bound and get its DeploymentID (objIDB)
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		DeploymentID workerBObjID = workerAcceptanceUtil.getWorkerDeployment().getDeploymentID();
		
		//Expect objIDB to be different from objIDA
		assertFalse(workerBObjID.equals(workerAObjID));
	}
	
	/**
	 * This test contains the following steps:
	 * 
	 *    1. Start a Worker with the idleness detector DISABLED;
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    4. Verify if the WORKER object is NOT bound
	 *    5. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "remoteMgPubKey1";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [remoteMgPubKey1]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    6. Verify if the WORKER object is bound and get its DeploymentID (objIDA)
	 *    7. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "remoteMgPubKey2";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [remoteMgPubKey2]."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    8. Verify if the WORKER object is bound and get its DeploymentID (objIDB)
	 *           * Expect objIDB to be different from objIDA
	 *    9. A client with the public key "remoteMgPubKey2" sends a startWork message;
	 *           * Verify if the following info message was logged: Worker is ready to start working for client [ClientID].
	 *           * Expect the Worker to send the client a Worker is Ready message
	 *   10. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "remoteMgPubKey3";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [remoteMgPubKey3]."
	 *           * Verify if the following debug message was logged: "Cleaning Worker."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *   11. Verify if the WORKER object is bound and get its DeploymentID (objIDC)
	 *           * Expect objIDC to be different from objIDB
	 * 
	 */
	@ReqTest(test=" AT-121.8", reqs="REQ121")
	@Test public void test_at_121_8_RemotePeerCommandsWorkerToWorkerForManyRemoteConsumers() throws Exception {
		//Start Worker with idleness detector DISABLED
		WorkerComponent component = req_004_Util.startWorker();
		
		//Master peer sends a setPeer message
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(
				component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "peerPubKey");
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());

		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "remoteMgPubKey1"
		RemoteWorkerManagementClient rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey", "remoteMgPubKey1");
		Worker worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//Verify if the WORKER is bound and get its DeploymentID (objIDA)
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		DeploymentID workerAObjID = workerAcceptanceUtil.getWorkerDeployment().getDeploymentID();
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "remoteMgPubKey2"
		rwmc = req_121_Util.workForMyGridOnAllocatedForMyGridWorker(component, "peerPubKey", "remoteMgPubKey2");
		worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//Verify if the WORKER is bound and get its DeploymentID (objIDB)
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		DeploymentID workerBObjID = workerAcceptanceUtil.getWorkerDeployment().getDeploymentID();
		
		//Expect objIDB to be different from objIDA
		assertFalse(workerBObjID.equals(workerAObjID));
		
		//A client with the public key "remoteMgPubKey2" sends a startWork message
		DeploymentID myGridID = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "remoteMgPubKey2"), "myGrid");
		
		req_079_Util.startWorkSuccessfully(component, worker, myGridID);
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "remoteMgPubKey3"
		rwmc = req_121_Util.workForMyGridOnAllocatedForMyGridWorker(component, "peerPubKey", "remoteMgPubKey3");
		worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//Verify if the WORKER is bound and get its DeploymentID (objIDC)
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		DeploymentID workerCObjID = workerAcceptanceUtil.getWorkerDeployment().getDeploymentID();
		
		//Expect objIDC to be different from objIDB
		assertFalse(workerCObjID.equals(workerBObjID));
	}
	
	/**
	 * This test contains the following steps:
	 * 
	 *    1. Start a Worker with the idleness detector DISABLED
	 *    2. The master peer sends a setPeer message to the Worker;
	 *           * Verify if the following info message was logged: The peer [peerID] set itself as manager of this Worker.
	 *           * Expect the Worker to send a status changed message to the peer, with the IDLE status
	 *    3. The master peer sends a workForPeer message to the Worker;
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a remote peer. Remote peer public key: [peerPubKey]."
	 *           * Verify if the following debug message was logged: "Status changed from IDLE to ALLOCATED_FOR_PEER."
	 *           * Expect the Worker to send the peer an allocated for peer status changed message, with a stub to the Remote Worker Management remote object
	 *    4. Verify if the WORKER object is NOT bound
	 *    5. The remote peer with the public key "peerPubKey" commands the Worker to work for the remote client with the public key "remoteMgPubKey1";
	 *           * Verify if the following info message was logged: "Remote peer commanded this Worker to work for a remote consumer. Remote consumer public key: [remoteMgPubKey1]."
	 *           * Verify if the following debug message was logged: "Status changed from ALLOCATED_FOR_PEER to ALLOCATED_FOR_MYGRID."
	 *           * Expect the Worker to send the remote peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *    6. A client with the public key "remoteMgPubKey1" sends a startWork message;
	 *           * Verify if the following info message was logged: Worker is ready to start working for client [ClientID].
	 *           * Expect the Worker to send the client a Worker is Ready message
	 *    7. Verify if the WORKER object is bound
	 *    8. Verify if the REMOTE_WORKER_MANAGEMENT object is bound
	 *    9. The master peer sends again a setPeer message to the Worker;
	 * 	         * Verify if the following warn message was logged: The peer [peerID1] set itself as manager of this Worker. This message was ignored. Because the master peer did not notify fail.
	 *   10. Verify if the WORKER object is bound
	 *   11. Verify if the REMOTE_WORKER_MANAGEMENT object is bound
	 *   12. The master peer sends a workForMyGrid message to the Worker;
	 *   		 * Verify if the following debug message was logged: Cleaning Worker. 	
	 *           * Verify if the following info message was logged: "Peer commanded this Worker to work for a local consumer. Local consumer public key: [localMgPubKey]."
	 *           * Expect the Worker to send the peer an allocated for mygrid status changed message, with a stub to the Worker remote object
	 *   13. A client with the public key "localMgPubKey" sends a startWork message;
	 *           * Verify if the following info message was logged: Worker is ready to start working for client [ClientID2].
	 *           * Expect the Worker to send the client a Worker is Ready message
	 *   14. The master peer sends again a setPeer message to the Worker;
	 * 	         * Verify if the following warn message was logged: The peer [peerID2] set itself as manager of this Worker. This message was ignored. Because the master peer did not notify fail. 
	 */
	@ReqTest(test=" AT-121.9", reqs="REQ121")
	@Test public void test_at_121_9_AllocatedWorkerForRemoteConsumerHasRedefinedPeer() throws Exception {
		//Start Worker with idleness detector DISABLED
		WorkerComponent component = req_004_Util.startWorker();
		
		//Master peer sends a setPeer message
		WorkerManagementClient wmc = req_090_Util.setKnownPeer(
				component, peerID, WorkerStatus.IDLE);
		
		//Master peer sends a workForPeer message
		req_006_Util.workForPeerOnIdleWorker(component, wmc, peerID.getPublicKey(), "peerPubKey");
		
		//Verify if the WORKER is NOT bound
		assertFalse(workerAcceptanceUtil.isWorkerBound());
		
		//The remote peer with the public key "peerPubKey" commands the Worker 
		// to work for the remote client with the public key "remoteMgPubKey1"
		RemoteWorkerManagementClient rwmc = req_121_Util.workForMyGridOnAllocatedForPeerWorker(component, "peerPubKey", "remoteMgPubKey1");
		Worker worker = req_121_Util.beginAllocationCompleted(component, rwmc);
		
		//A client with the public key "remoteMgPubKey1" sends a startWork message
		DeploymentID clientID1 = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "remoteMgPubKey1"), "myGrid");
		
		req_079_Util.startWorkSuccessfully(component, worker, clientID1);
		
		//Verify if the REMOTE_WORKER_MANAGEMENT is bound
		assertTrue(workerAcceptanceUtil.isRemoteWorkerManagementBound());
		
		//Verify if the WORKER is bound
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		
		//Master peer sends a setPeer message
		req_090_Util.setPeerByMasterPeerFromSameLocation(component, peerID, WorkerStatus.ALLOCATED_FOR_BROKER, wmc);
		
		//Verify if the REMOTE_WORKER_MANAGEMENT is bound
		assertTrue(workerAcceptanceUtil.isRemoteWorkerManagementBound());
		
		//Verify if the WORKER is bound
		assertTrue(workerAcceptanceUtil.isWorkerBound());
		
		//The master peer sends a workForMyGrid message the Worker
		// to work for the local client with public key "localMgPubKey"
		req_092_Util.workForMyGridOnAllocatedForMyGridWorker(component, wmc, "localMgPubKey");
		worker = req_092_Util.beginAllocationCompleted(component, wmc);
		
		//A client with the public key "localMgPubKey" sends a startWork message
		DeploymentID clientID2 = new DeploymentID(new ContainerID("mgUserName", "mgServer", "mgModule", "localMgPubKey"), "myGrid");
		
		req_079_Util.startWorkSuccessfully(component, worker, clientID2);
		
		//Master peer sends a setPeer message
		DeploymentID anotherPeerID = new DeploymentID(new ContainerID("peerUserName", "peerServerName", "peerModule", peerID.getPublicKey()),
				"peer");
		
		req_090_Util.setPeerByMasterPeerFromDiffLocation(component, anotherPeerID, WorkerStatus.ALLOCATED_FOR_BROKER);
	}
	
}
